declare global {
    interface Window {
        __TAURI_INVOKE__<T>(cmd: string, args?: Record<string, unknown>): Promise<T>;
    }
}

import type {
    CorrelationMatrix,
    Column, IndicatorComb, IndicatorCombinationFilter, IpcResponse, ListParams,
    Security, SecurityFilter, Table, TradeStrategy, TradeStrategyFilter, TrendLineResult, UpdateParams,
    TradeBotFilter,
    TradeBot,
    GetParams, FudaThing, FudaRecord,
    IndicatorFilter,
    TradeOrderFilter,
    TradeOrder,
    TradeStrategyIndicator,
    KlineFilter,
    FudaHistoryFilter,
    KlineFlat, ChartJsDataWrapper
} from "./bindings";
import type { Indicator } from "./bindings/Indicator";
import type { TradeRequest } from "./bindings/TradeRequest";
import type { TradeStrategyMaLine } from "./bindings/TradeStrategyMaLine";
import type { FudaHistory } from "./bindings/FudaHistory";

// Function avoids 'window not defined' in SSR
const invoke = () => window.__TAURI_INVOKE__;

export function greet(name: string) {
    return invoke()<string>("greet", { name })
}

export function greet2(args: MyCustomArgumentType) {
    return invoke()<MyCustomReturnType>("greet2", { args })
}

export type MyCustomArgumentType = { foo: string; bar: number }
export type MyCustomReturnType = { some_field: string }


export function greet3(args: MyCustomArgumentType) {
    return invoke()<Security>("greet3", { args })
}

export function list_securities(args: ListParams<SecurityFilter>) {
    return invoke()<IpcResponse<Security[]>>("list_securities", { args })
}


export function get_security(args: GetParams) {
    return invoke()<IpcResponse<Security>>("get_security", { args })
}

export function list_kline_flats(args: ListParams<KlineFilter>) {
    return invoke()<IpcResponse<KlineFlat[]>>("list_kline_flats", { args })
}

export function list_trend_line_klines(args: ListParams<KlineFilter>) {
    return invoke()<IpcResponse<TrendLineResult>>("list_trend_line_klines", { args })
}

export function list_kline_datapoints(args: ListParams<KlineFilter>) {
    return invoke()<IpcResponse<ChartJsDataWrapper>>("list_kline_datapoints", { args })
}


export function list_indicators_correlation_matrix(args: ListParams<KlineFilter>) {
    return invoke()<IpcResponse<CorrelationMatrix>>("list_indicators_correlation_matrix", { args })
}


export function list_indicator_combinations(args: ListParams<IndicatorCombinationFilter>) {
    return invoke()<IpcResponse<IndicatorComb[]>>("list_indicator_combinations", { args })
}

export function get_kline_flat_table() {
    return invoke()<IpcResponse<Table>>("get_kline_flat_table", {})
}


export function update_kline_flat_table_column(args: UpdateParams<Column>) {
    return invoke()<IpcResponse<Column>>("update_kline_flat_table_column", { args })
}


export function list_trade_strategies(args: ListParams<TradeStrategyFilter>) {
    return invoke()<IpcResponse<TradeStrategy[]>>("list_trade_strategies", { args })
}

export function get_trade_strategy(args: GetParams) {
    return invoke()<IpcResponse<TradeStrategy>>("get_trade_strategy", { args })
}


export function verify_trade_strategy(args: GetParams) {
    return invoke()<IpcResponse<String>>("verify_trade_strategy", { args })
}


export function publish_trade_strategy(args: GetParams) {
    return invoke()<IpcResponse<FudaThing>>("publish_trade_strategy", { args })
}

export function update_trade_strategy(args: UpdateParams<TradeStrategy>) {
    return invoke()<IpcResponse<TradeStrategy>>("update_trade_strategy", { args })
}

export function update_trade_strategy_indicator(args: UpdateParams<TradeStrategyIndicator>) {
    return invoke()<IpcResponse<TradeStrategy>>("update_trade_strategy_indicator", { args })
}


export function update_trade_strategy_maline(args: UpdateParams<TradeStrategyMaLine>) {
    return invoke()<IpcResponse<TradeStrategy>>("update_trade_strategy_maline", { args })
}


export function list_trade_bots(args: ListParams<TradeBotFilter>) {
    return invoke()<IpcResponse<TradeBot[]>>("list_trade_bots", { args })
}

export function list_trade_orders(args: ListParams<TradeOrderFilter>) {
    return invoke()<IpcResponse<TradeOrder[]>>("list_trade_orders", { args })
}


export function get_trade_bot(args: GetParams) {
    return invoke()<IpcResponse<TradeBot>>("get_trade_bot", { args })
}

export function update_trade_bot(args: UpdateParams<TradeBot>) {
    return invoke()<IpcResponse<FudaRecord>>("update_trade_bot", { args })
}


export function start_trade_bot_backtest(args: GetParams) {
    return invoke()<IpcResponse<TradeRequest[]>>("start_trade_bot_backtest", { args })
}


export function list_indicators(args: ListParams<IndicatorFilter>) {
    return invoke()<IpcResponse<Indicator[]>>("list_indicators", { args })
}



export function list_history(args: ListParams<FudaHistoryFilter>) {
    return invoke()<IpcResponse<FudaHistory[]>>("list_history", { args })
}